home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / utility / utilmisc / queue.lzh / queue_3.1 / queue_test.c < prev    next >
C/C++ Source or Header  |  1996-11-28  |  7KB  |  331 lines

  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. #include <exec/exec.h>
  7. #include <proto/exec.h>
  8. #include <proto/dos.h>
  9.  
  10. #include "queue.h"
  11.  
  12. #include "queue_library.h" /* so we can look at internals */
  13.  
  14. #if 1
  15. #define LISTEN_REOPEN
  16. #define SEND_REOPEN
  17. #endif
  18.  
  19. #if defined (__GNUC__)
  20. #include "queue_inline.h"
  21. #elif defined (__SASC)
  22. #include "queue_pragmas.h"
  23. #endif
  24.  
  25. #if !defined (__SASC)
  26. struct ExecBase *SysBase = NULL;
  27. struct DosLibrary *DOSBase = NULL;
  28. #endif
  29. struct Library *QueueBase = NULL;
  30.  
  31. ULONG sigbit = -1;
  32. QMessage *Qmsg = NULL;
  33.  
  34. #define QMSG_DATA_SIZE 1
  35. #define PID(msg) (*(ULONG *)(msg->qm_Data))
  36.  
  37. void
  38. Block (int *abort)
  39. {
  40.   int r;
  41.  
  42.   if (r = rand () % 3)
  43.     Delay (r * 5);
  44.   if (SetSignal (0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  45.     *abort = 1;
  46. }
  47.  
  48. void
  49. cleanup (void)
  50. {
  51.   if (sigbit != -1)
  52.   {
  53.     FreeSignal (sigbit);
  54.   }
  55. #if !defined (__SASC)
  56.   if (DOSBase)
  57.   {
  58.     CloseLibrary ((struct Library *) DOSBase);
  59.   }
  60. #endif
  61.   if (QueueBase)
  62.   {
  63.     if (Qmsg)
  64.       QFreeMsg (Qmsg, QMSG_DATA_SIZE);
  65.     CloseLibrary (QueueBase);
  66.   }
  67. }
  68.  
  69. void
  70. PrintQueue (QHandle *qhandle)
  71. {
  72.   QueueNode *qn = ((QueueHandle *) qhandle) -> qh_QNode;
  73.   QueueHandle *qh = (QueueHandle *) qhandle;
  74.   char s[512], *ptr;
  75.   QMessage *msg, *next, *err_msg = NULL;
  76.   int count = 0, replies, qnread;
  77.  
  78.   // ObtainSemaphore (qn -> qn_Semaphore);
  79.   Forbid ();
  80.   ptr = s;
  81.   msg = (QMessage *) qn -> qn_List.lh_Head;
  82.   while (next = (QMessage *) msg -> qm_MinNode.mln_Succ)
  83.   {
  84.     switch (msg -> qm_Status)
  85.     {
  86.       case QMS_ACTIVE:
  87.         sprintf (ptr, "[%da:%d],", PID (msg), msg -> qm_Replies); break;
  88.       case QMS_REMOVED:
  89.         sprintf (ptr, "[%dr:%d],", PID (msg), msg -> qm_Replies); break;
  90.       case QMS_MARKER:
  91.         sprintf (ptr, "[m],"); break;
  92.       default:
  93.         sprintf (ptr, "[** %x **],", msg -> qm_Status); break;
  94.     }
  95.     if (msg -> qm_Status == QMS_ACTIVE ||
  96.         msg -> qm_Status == QMS_REMOVED)
  97.     {
  98.       if (msg -> qm_Replies > qn -> qn_Read)
  99.         err_msg = msg;
  100.     }
  101.     ptr = s + strlen (s);
  102.     msg = next;
  103.     if (count ++ > 42)
  104.       break;
  105.   }
  106.   if (qh -> qh_Mode == QMODE_LISTEN)
  107.   {
  108.     if (msg = qh -> qh_un.qhl.qhl_Message)
  109.       sprintf (ptr, " current = %d.\n", PID (msg));
  110.     else
  111.       sprintf (ptr, " current = <null>.\n");
  112.   }
  113.   else
  114.   {
  115.     sprintf (ptr, " qn_Read = %d.\n", qn -> qn_Read);
  116.   }
  117.   if (err_msg)
  118.   {
  119.     replies = err_msg -> qm_Replies;
  120.     qnread  = qn -> qn_Read;
  121.   }
  122.   Permit ();
  123.   // ReleaseSemaphore (qn -> qn_Semaphore);
  124.   printf (s);
  125.  
  126.   if (err_msg)
  127.   {
  128.     printf ("\nToo many replies: %d (qn_Read = %d).\n", replies, qnread);            
  129.     while (1)
  130.       Delay (100);
  131.   }
  132. }
  133.  
  134. int
  135. main (int argc, char *argv[])
  136. {
  137.   ULONG sigmask;
  138.   QMessage *msg = NULL;
  139.   QHandle qh = NULL;
  140.   char *qn, *queuename = "testqueue";
  141.   int r, abort = 0, reopen = 1;
  142.   ULONG pid = 0;
  143.  
  144.   if (argc == 2)
  145.   {
  146.     pid = ((struct Process *) FindTask (0)) -> pr_TaskNum;
  147.     printf ("Server ( pid = %ld ).\n", pid);
  148.   }
  149.   else
  150.     printf ("Client.\n", pid);
  151.  
  152.   if (qn = getenv ("TESTQUEUE"))
  153.   {
  154.     printf ("Queue = %s.\n", qn);
  155.     queuename = qn;
  156.   }
  157.  
  158. #if !defined (__SASC)
  159.   SysBase = *(struct ExecBase **)4;
  160.   if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
  161.     return 20;
  162. #endif
  163.  
  164.   atexit (cleanup);
  165.  
  166.   if ((sigbit = AllocSignal (-1)) == -1)
  167.   {
  168.     printf ("Failed to allocate signal.\n");
  169.     return 20;
  170.   }
  171.   sigmask = 1 << sigbit;
  172.  
  173.   if (!(QueueBase = OpenLibrary ("queue.library", 0)))
  174.   {
  175.     printf ("Failed to open queue.library.\n");
  176.     return 20;
  177.   }
  178.   if (!(Qmsg = QAllocMsg ( QMSG_DATA_SIZE )))
  179.   {
  180.     printf ("Couldn't allocate message.\n");
  181.     return 20;
  182.   }
  183.   if (!pid) /* Client */
  184.   {
  185.     r = time (NULL);
  186.     srand (r);
  187.  
  188.     while (1)
  189.     {
  190.       if (!abort && !reopen)
  191.       {
  192.         printf ("Waiting ...\n");
  193.         abort = Wait (sigmask | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C;
  194.         printf ("Signal.\n");
  195.       }
  196.       if (abort || reopen)
  197.       {
  198.         if (qh)
  199.         {
  200.       Forbid ();
  201.           while (msg = QGetMsg (qh));
  202.       QClose (qh);
  203.       Permit ();
  204.           if (abort)
  205.           {
  206.             printf ("Exiting.\n");
  207.         return 0;
  208.       }
  209.         }
  210.       }
  211.       if (reopen)
  212.       {
  213.     Delay (50);
  214.  
  215.         if (!(qh = QOpen (queuename, QMODE_LISTEN, sigbit)))
  216.         {
  217.           printf ("Failed to open \"%s\" queue.\n", queuename);
  218.           return 20;
  219.         }
  220.         printf ("Queue \"%s\" opened.\n", queuename);
  221.         reopen = 0;
  222.       }
  223.  
  224.       PrintQueue (qh);
  225.  
  226.       if (rand () > RAND_MAX/2) /*** Process all messages ***/
  227.       {
  228.         r = 0;
  229.  
  230.         while (msg = QGetMsg (qh))
  231.         {
  232.       printf ("Got message from %d.\n", PID (msg));
  233.           r ++;
  234.     }
  235.         if (!r)
  236.           printf ("Got no message(s).\n");
  237.       }
  238.       else /*** Reply one message & block ***/
  239.       {
  240.         if (msg = QGetMsg (qh))
  241.       printf ("Got message from %d (reply, block).\n", PID (msg));
  242.         else
  243.           printf ("Got no message (reply, block).\n");
  244.  
  245.         if (rand () > RAND_MAX/2)
  246.         {
  247.       QReplyMsg (qh);
  248.           Block (&abort);
  249.         }
  250.         else
  251.         {
  252.           Block (&abort);
  253.       QReplyMsg (qh);
  254.         }
  255.       }
  256. #ifdef LISTEN_REOPEN
  257.       if (rand () < RAND_MAX/10)
  258.         reopen = 1;
  259. #endif
  260.     }
  261.   }
  262.   else
  263.   {
  264.     PID (Qmsg) = pid;
  265.  
  266.     while (1)
  267.     {
  268.       if (!abort && !reopen)
  269.       {
  270.         printf ("Waiting ...\n");
  271.         abort = Wait (sigmask | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C;
  272.         printf ("Signal.\n");
  273.       }
  274.       if (abort || reopen) 
  275.       {
  276.         if (qh)
  277.         {
  278.           while ((r = QClose (qh)) > 0)
  279.           {
  280.             printf ("Cannot exit: %d message(s) left in queue.\n", r);
  281.             PrintQueue (qh);
  282.         Delay (10);
  283.             QGetMsg (qh);
  284.           }
  285.           if (abort)
  286.           {
  287.             printf ("All done.\n");
  288.             return 0;
  289.           }
  290.         }
  291.       }
  292.       if (reopen)
  293.       {
  294.         if (!(qh = QOpen (queuename, QMODE_SEND, sigbit)))
  295.         {
  296.           printf ("Failed to open \"%s\" queue.\n", queuename);
  297.           return 20;
  298.         }
  299.         printf ("Queue \"%s\" opened.\n", queuename);
  300.     msg = Qmsg;
  301.         reopen = 0;
  302.       }
  303.       else
  304.       {
  305.         msg = QGetMsg (qh);
  306.         if (msg == Qmsg)
  307.           printf ("Got my message (%d).\n", PID (msg));
  308.         else if (msg)
  309.           printf ("Got wrong message (%d).\n", PID (msg));
  310.         else
  311.           printf ("Got no message.\n");
  312.  
  313.         Block (&abort);
  314.       }
  315.       if (!abort)
  316.       {
  317. #ifdef SEND_REOPEN /* ERROR */
  318.         if (rand () < RAND_MAX/10)
  319.           reopen = 1;
  320. #endif
  321.         if (msg == Qmsg)
  322.         {
  323.           printf ("Sending message (%d): ", PID (msg));
  324.           QAddMsg (qh, Qmsg);
  325.           PrintQueue (qh);
  326.         }
  327.       }
  328.     }
  329.   }
  330. }
  331.